package com.ruoyi.binance.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.binance.domain.*;
import com.ruoyi.binance.mapper.Binance15minDayAveMapper;
import com.ruoyi.binance.mapper.BinanceAutoSingleCellMapper;
import com.ruoyi.binance.mapper.BinanceAverageBuySellMapper;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.binance.mapper.BinanceDailyMarketMapper;
import com.ruoyi.binance.service.IBinanceDailyMarketService;

/**
 * 日行情Service业务层处理
 * 
 * @author zq
 * @date 2025-09-10
 */
@Service
public class BinanceDailyMarketServiceImpl implements IBinanceDailyMarketService 
{
    @Autowired
    private BinanceDailyMarketMapper binanceDailyMarketMapper;
    @Autowired
    private BinanceAverageBuySellMapper binanceAverageBuySellMapper;
    @Autowired
    private Binance15minDayAveMapper binance15minDayAveMapper;
    @Autowired
    private BinanceAutoSingleCellMapper binanceAutoSingleCellMapper;

    /**
     * 查询日行情
     * 
     * @param code 日行情主键
     * @return 日行情
     */
    @Override
    public BinanceDailyMarket selectBinanceDailyMarketByCodeAndDate(String code, String date)
    {
        return binanceDailyMarketMapper.selectBinanceDailyMarketByCodeAndDate(code, date);
    }

    /**
     * 查询日行情列表
     * 
     * @param binanceDailyMarket 日行情
     * @return 日行情
     */
    @Override
    public List<BinanceDailyMarket> selectBinanceDailyMarketList(BinanceDailyMarket binanceDailyMarket)
    {
        return binanceDailyMarketMapper.selectBinanceDailyMarketList(binanceDailyMarket);
    }

    /**
     * 新增日行情
     * 
     * @param binanceDailyMarket 日行情
     * @return 结果
     */
    @Override
    public int insertBinanceDailyMarket(BinanceDailyMarket binanceDailyMarket)
    {
        binanceDailyMarket.setCreateTime(DateUtils.getNowDate());
        return binanceDailyMarketMapper.insertBinanceDailyMarket(binanceDailyMarket);
    }

    /**
     * 修改日行情
     * 
     * @param binanceDailyMarket 日行情
     * @return 结果
     */
    @Override
    public int updateBinanceDailyMarket(BinanceDailyMarket binanceDailyMarket)
    {
        binanceDailyMarket.setUpdateTime(DateUtils.getNowDate());
        return binanceDailyMarketMapper.updateBinanceDailyMarket(binanceDailyMarket);
    }

    /**
     * 批量删除日行情
     * 
     * @param codes 需要删除的日行情主键
     * @return 结果
     */
    @Override
    public int deleteBinanceDailyMarketByCodes(String[] codes)
    {
        return binanceDailyMarketMapper.deleteBinanceDailyMarketByCodes(codes);
    }

    /**
     * 删除日行情信息
     * 
     * @param code 日行情主键
     * @return 结果
     */
    @Override
    public int deleteBinanceDailyMarketByCode(String code)
    {
        return binanceDailyMarketMapper.deleteBinanceDailyMarketByCode(code);
    }

    @Override
    public void saveOrUpdateTradingDay(String code, JSONObject jsonObject) {
        if (jsonObject == null) {
            return;
        }
        BinanceDailyMarket dailyMarket = new BinanceDailyMarket();
        dailyMarket.setCode(code);
        dailyMarket.setDate(jsonObject.getDate("openTime"));
        dailyMarket.setOpenTime(jsonObject.getDate("openTime"));
        dailyMarket.setCloseTime(jsonObject.getDate("closeTime"));
        dailyMarket.setOpenPrice(jsonObject.getBigDecimal("openPrice"));
        dailyMarket.setHighPrice(jsonObject.getBigDecimal("highPrice"));
        dailyMarket.setLowPrice(jsonObject.getBigDecimal("lowPrice"));
        dailyMarket.setLastPrice(jsonObject.getBigDecimal("lastPrice"));
        dailyMarket.setPriceChange(jsonObject.getBigDecimal("priceChange"));
        dailyMarket.setPriceChangePercent(jsonObject.getBigDecimal("priceChangePercent"));
        dailyMarket.setWeightedAvgPrice(jsonObject.getBigDecimal("weightedAvgPrice"));
        dailyMarket.setVolume(jsonObject.getBigDecimal("volume"));
        dailyMarket.setQuoteVolume(jsonObject.getBigDecimal("quoteVolume"));
        dailyMarket.setFirstTradeId(jsonObject.getLong("firstId"));
        dailyMarket.setLastTradeId(jsonObject.getLong("lastId"));
        dailyMarket.setTradeCount(jsonObject.getLong("count"));
        int updated = updateBinanceDailyMarket(dailyMarket);
        if (updated == 0) {
            insertBinanceDailyMarket(dailyMarket);
        }
    }

    @Override
    public void saveOrUpdateTradingDay(String code, JSONArray jsonArray) {
        if (jsonArray == null || jsonArray.isEmpty()) {
            return;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONArray array = jsonArray.getJSONArray(i);
            BinanceDailyMarket minK = new BinanceDailyMarket();
            minK.setCode(code);
            minK.setDate(array.getDate(0));
            minK.setOpenTime(array.getDate(0));
            minK.setOpenPrice(array.getBigDecimal(1));
            minK.setHighPrice(array.getBigDecimal(2));
            minK.setLowPrice(array.getBigDecimal(3));
            minK.setLastPrice(array.getBigDecimal(4));
            minK.setPriceChange(new BigDecimal("0"));
            minK.setPriceChangePercent(new BigDecimal("0"));
            minK.setWeightedAvgPrice(array.getBigDecimal(7).divide(array.getBigDecimal(5), 8, RoundingMode.HALF_UP));
            minK.setVolume(array.getBigDecimal(5));
            minK.setCloseTime(array.getDate(6));
            minK.setQuoteVolume(array.getBigDecimal(7));
            minK.setFirstTradeId(0L);
            minK.setLastTradeId(0L);
            minK.setTradeCount(array.getLong(8));
            int updated = updateBinanceDailyMarket(minK);
            if (updated == 0) {
                insertBinanceDailyMarket(minK);
            }
        }
    }

    @Override
    public void autoHighAndLowRange(BinanceAverageBuySell bean, String date) {
        BigDecimal aveHigh = binanceDailyMarketMapper.selectBinanceDailyMarketAveHigh(bean.getCode(), date);
        BigDecimal aveLow = binanceDailyMarketMapper.selectBinanceDailyMarketAveLow(bean.getCode(), date);
        BigDecimal aveWeightedAvgPrice = binanceDailyMarketMapper.selectBinanceDailyMarketAveWeightedAvgPrice(bean.getCode(), date);

        if (aveHigh == null || aveLow == null || aveWeightedAvgPrice == null) {
            return;
        }
        //判断 aveHigh 是否大于 binance15minDayAve.price
        if (aveHigh.compareTo(aveWeightedAvgPrice) <= 0) {
            return;
        }
        //判断 aveLow 是否小于 binance15minDayAve.price
        if (aveLow.compareTo(aveWeightedAvgPrice) >= 0) {
            return;
        }
        //计算下破百分比  （binance15minDayAve.price - aveLow)/binance15minDayAve.price * 100
        BigDecimal breDown = aveWeightedAvgPrice.subtract(aveLow).divide(aveWeightedAvgPrice, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("99"));

        //计算上穿百分比  （aveHigh - binance15minDayAve.price)/binance15minDayAve.price * 100
        BigDecimal breAbove = aveHigh.subtract(aveWeightedAvgPrice).divide(aveWeightedAvgPrice, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("99"));

        //自动更新均价配置
        bean.setRemark("更新前：" + bean.getBreDown() + " - " + bean.getBreAbove());
        bean.setBreDown(breDown);
        bean.setBreAbove(breAbove);
        bean.setUpdateTime(new Date());
    }
    @Override
    public void autoHighAndLowRange(BinanceAverageBuySell bean) {
        BigDecimal aveHigh = binanceDailyMarketMapper.selectBinanceDailyMarketAveHigh(bean.getCode(), DateUtils.getDate());
        BigDecimal aveLow = binanceDailyMarketMapper.selectBinanceDailyMarketAveLow(bean.getCode(), DateUtils.getDate());
        BigDecimal aveWeightedAvgPrice = binanceDailyMarketMapper.selectBinanceDailyMarketAveWeightedAvgPrice(bean.getCode(), DateUtils.getDate());

        if (aveHigh == null || aveLow == null || aveWeightedAvgPrice == null) {
            return;
        }
        //判断 aveHigh 是否大于 binance15minDayAve.price
        if (aveHigh.compareTo(aveWeightedAvgPrice) <= 0) {
            return;
        }
        //判断 aveLow 是否小于 binance15minDayAve.price
        if (aveLow.compareTo(aveWeightedAvgPrice) >= 0) {
            return;
        }
        //计算下破百分比  （binance15minDayAve.price - aveLow)/binance15minDayAve.price * 100
        BigDecimal breDown = aveWeightedAvgPrice.subtract(aveLow).divide(aveWeightedAvgPrice, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("99"));

        //计算上穿百分比  （aveHigh - binance15minDayAve.price)/binance15minDayAve.price * 100
        BigDecimal breAbove = aveHigh.subtract(aveWeightedAvgPrice).divide(aveWeightedAvgPrice, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("99"));

        //自动更新均价配置
        bean.setRemark("更新前：" + bean.getBreDown() + " - " + bean.getBreAbove());
        bean.setBreDown(breDown);
        bean.setBreAbove(breAbove);
        bean.setUpdateTime(new Date());
        binanceAverageBuySellMapper.updateBinanceAverageBuySell(bean);
    }

    @Override
    public void autoHighAndLowRange(BinanceAutoSingleCell bean) {
        BigDecimal aveHigh = binanceDailyMarketMapper.selectBinanceDailyMarketAveHigh(bean.getCode(), DateUtils.getDate());
        BigDecimal aveLow = binanceDailyMarketMapper.selectBinanceDailyMarketAveLow(bean.getCode(), DateUtils.getDate());
        if (aveHigh == null || aveLow == null) {
            return;
        }
        BigDecimal diff = aveHigh.subtract(aveLow);
        BigDecimal divide = diff.multiply(new BigDecimal("100").subtract(bean.getCalculateAmplitude()))
                .divide(new BigDecimal("100"), 8, RoundingMode.HALF_UP);

        BigDecimal buyPric = aveLow.add(divide);
        BigDecimal sellPric = aveHigh.subtract(divide);

        bean.setRemark("更新前：" + bean.getBuyPric() + " - " + bean.getSellPric());
        bean.setBuyPric(buyPric);
        bean.setSellPric(sellPric);
        bean.setUpdateTime(new Date());
        binanceAutoSingleCellMapper.updateBinanceAutoSingleCell(bean);
    }
    @Override
    public void autoHighAndLowRange(BinanceAutoSingleCell bean, String date) {
        BigDecimal aveHigh = binanceDailyMarketMapper.selectBinanceDailyMarketAveHigh(bean.getCode(), date);
        BigDecimal aveLow = binanceDailyMarketMapper.selectBinanceDailyMarketAveLow(bean.getCode(), date);
        if (aveHigh == null || aveLow == null) {
            return;
        }
        BigDecimal diff = aveHigh.subtract(aveLow);
        BigDecimal divide = diff.multiply(new BigDecimal("100").subtract(bean.getCalculateAmplitude()))
                .divide(new BigDecimal("100"), 8, RoundingMode.HALF_UP);

        BigDecimal buyPric = aveLow.add(divide);
        BigDecimal sellPric = aveHigh.subtract(divide);

        bean.setRemark("更新前：" + bean.getBuyPric() + " - " + bean.getSellPric());
        bean.setBuyPric(buyPric);
        bean.setSellPric(sellPric);
        bean.setUpdateTime(new Date());
    }
}
